package com.vitalfit.service.serviceImpl;

import com.vitalfit.model.dto.FoodCategoryDTO;
import com.vitalfit.model.entity.food.FoodCategory;
import com.vitalfit.model.vo.FoodCategoryPageVO;
import com.vitalfit.repository.FoodCategoryRepository;
import com.vitalfit.service.FoodCategoryService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class FoodCategoryServiceImpl implements FoodCategoryService {

    private final FoodCategoryRepository foodCategoryRepository;

    @Override
    @Transactional
    public FoodCategory addCategory(FoodCategoryDTO foodCategoryDTO) {
        // Check if category already exists to prevent duplicates
        FoodCategory existingCategory = foodCategoryRepository.findByCategoryName(foodCategoryDTO.getCategoryName());
        if (existingCategory != null) {
            throw new RuntimeException("Food category already exists with name: " + foodCategoryDTO.getCategoryName());
        }

        // Map DTO to entity
        FoodCategory foodCategory = new FoodCategory();
        foodCategory.setCategoryName(foodCategoryDTO.getCategoryName());

        // Save new category in database
        return foodCategoryRepository.save(foodCategory);
    }

    @Override
    @Transactional
    public FoodCategory updateCategory(FoodCategoryDTO foodCategoryDTO) {
        // Find existing category and throw an exception if not found
        FoodCategory existingCategory = foodCategoryRepository.findById(foodCategoryDTO.getId())
                .orElseThrow(() ->
                        new IllegalArgumentException("Category with ID " + foodCategoryDTO.getId() + " not found"));

        // Update the category name based on provided DTO
        existingCategory.setCategoryName(foodCategoryDTO.getCategoryName());
        return foodCategoryRepository.save(existingCategory);
    }

    @Override
    @Transactional(readOnly = true)
    public FoodCategoryPageVO listAllCategories(int page, int size) {
        // Create pageable object to apply pagination
        Pageable pageable = PageRequest.of(page, size);

        // Fetch paginated categories
        Page<FoodCategory> foodCategoryPage = foodCategoryRepository.findAll(pageable);

        // Map page data to VO
        FoodCategoryPageVO foodCategoryPageVO = new FoodCategoryPageVO();
        foodCategoryPageVO.setTotalPages(foodCategoryPage.getTotalPages());
        foodCategoryPageVO.setTotalElements(foodCategoryPage.getTotalElements());
        foodCategoryPageVO.setContent(foodCategoryPage.getContent());
        return foodCategoryPageVO;
    }

    @Override
    @Transactional(readOnly = true)
    public FoodCategory getCategoryById(Integer categoryId) {
        // Fetch a single category by ID and throw an exception if not found
        return foodCategoryRepository.findById(categoryId)
                .orElseThrow(() -> new IllegalArgumentException("Category with ID " + categoryId + " not found"));
    }
}
